import store from '@/store';
import { LOGIN } from '@/store/modules/app/actions';
import Common from '@/utils/common.js';
import formats from '@/utils/formats.js';

let channel = ''
// #ifdef APP-PLUS
channel = 'app';
// #endif
// #ifdef MP-WEIXIN
channel = 'weixin';
// #endif
// #ifdef H5
channel = 'h5';
// #endif
// console.log(channel)

// 统一请求
// console.log('process.env.NODE_ENV', process.env.NODE_ENV === 'production', process.env.NODE_ENV === 'development');
const accountInfo = wx.getAccountInfoSync();
// env类型 develop:开发版、trial:体验版、release:正式版
let env = accountInfo.miniProgram.envVersion;
if (process.env.NODE_ENV === 'production') env = 'release';
// const isRelease = env === 'release';
const isRelease = false;

const wImgHost = 'https://dpc.way-s.cn/admin';
const wStatus = {
	// 开发版
	develop: wImgHost + '/test',
	// 体验版
	trial: wImgHost,
	// 正式版
	release: wImgHost
};
const wImgBaseURL = (wStatus[env] || wImgHost) + '/static/images/weixin/';

const host = 'https://dpc.way-s.cn/mvp';
const status = {
	// 开发版
	develop: host + '/test',
	// 体验版
	trial: host,
	// 正式版
	release: host
};

const baseURL = status[env] || host;

let isLoging = false;
let loginCount = 0;
const instance = async (url, options, showErrTip) => {
	if (url.indexOf('http') === -1) url = baseURL + url

	const authorization = store.state.app.token || await Common.getStorage('login@token') || '';
	let header = {
		'Authorization': authorization,
		'Content-Type': 'application/json; charset=UTF-8'
		// 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
	}
	if (channel) header.Channel = channel
	if (options.header) header = {...header, ...options.header}
	options.method = options.method || 'GET'

	let [error, res] = await uni.request({
		url: url,
		header: header,
		method: options.method,
		data: options.data,
		timeout: 20000,
	});

	if (res && res.data && (res.data.code === 401 || res.data.code === 403)) { // token失效或未登录
		if (!isRelease) console.error('token 失效，url:' + url, options.data, res, error);
		if (loginCount <= 10) {
			if (isLoging) {
				await awaitLoginTime();
				return instance(url, options, showErrTip);
			} else {
				loginCount += 1;
				store.commit('setToken', { token: '' });
				isLoging = true;
				try {
					await store.dispatch(LOGIN);
				} catch (error) {
					isLoging = false;
					return null;
				}
				isLoging = false;
				return instance(url, options, showErrTip);
			}
		} else {
			setTimeout(() => {
				loginCount = 0;
			}, 5000);
		}
	}
	if (!url.includes('/sso/wxLogin')) {
		loginCount = 0;
	}
	// if (res && res.data.code !== 200) {
	// 	console.log(url, res);
	// }
	if (error) {
		if (!isRelease) console.error('url:' + url, options.data, res, error);
	} else if (res && res.data.code !== 200) {
		if (showErrTip) {
			uni.showToast({
				title: res.data.message || '操作失败',
				icon: 'error',
			});
		}
		if (!isRelease) console.error('url:' + url, options.data, res, error);
	} else {
		if (!isRelease && !(url.indexOf('community/message/getMessageCount') > -1) ) console.log('url:' + url, options.data, res, error);
	}
	return res
}

const instanceUploadFile = async (options, resolve, reject) => {
	const { url, params, events: { success, fail, complete, onProgressUpdate } = {} } = options;
	const {
		name = 'file',
		filePath,
		formData,
		header,
	} = params;
	const authorization = store.state.app.token || await Common.getStorage('login@token') || '';
	const headerOption = {
		...header,
		'Authorization': authorization,
		'content-Type': 'multipart/form-data',
	}
	const task = uni.uploadFile({
		url,
		filePath,
		name,
		formData,
		header: headerOption,
		success: res => {
			// 判断是否json字符串，将其转为json格式
			try {
				const data = formats.isJSON(res.data) ? JSON.parse(res.data) : null;
				console.log('uploadFile success', res, data);
				if (![200, 201, 204].includes(res.statusCode) || (data && data.code !== 200)) {
					console.log('error', data);
					if (data && (data.code === 401 || data.code === 403)) { // token失效或未登录
						tokenInValid(options, resolve, reject);
					}
				} else if (!data) {
					if (fail) fail(e);
					reject(e);
				} else {
					loginCount = 0;
					// 上传成功
					if (success) success(data);
					resolve(data);
				}
			} catch (error) {
				console.error(error);
				if (fail) fail(error);
				reject(error);
			}
		},
		fail: e => {
			if (fail) fail(e);
			reject(e);
		},
		complete: res => {
			if (complete) complete(res);
		}
	});
	if (onProgressUpdate) task.onProgressUpdate = onProgressUpdate;
}

const tokenInValid = async (options, resolve, reject) => {
	if (loginCount <= 30) {
		if (isLoging) {
			await awaitLoginTime();
			instanceUploadFile(options, resolve, reject);
		} else {
			loginCount += 1;
			store.commit('setToken', { token: '' });
			isLoging = true;
			try {
				await store.dispatch(LOGIN);
			} catch (error) {

			}
			isLoging = false;
			instanceUploadFile(options, resolve, reject);
		}
	}
}

function awaitLoginTime(time = 500) {
	return new Promise((resolve, reject) => {
		const interval = setInterval(() => {
			const authorization = store.state.app.token || Common.getStorage('login@token');
			if (!!authorization) {
				if (interval) clearInterval(interval);
				resolve(true);
			}
		}, time);
	});
}

const prepfixUrl = (http, prefix) => {
	if (http) {
		// const baseURL = status[env] || host;
		// return (process.env.NODE_ENV !== 'production' ? baseURL : 'http://10.10.25.81:8083') + prefix;
		return http;
	}
	return prefix;
}

const http = {
	baseURL,
	wImgBaseURL,
	homePrefixUrl: prepfixUrl(null, '/api/community'), // http://10.10.25.81:8083 /community
	commodityPrefixUrl: prepfixUrl(null, '/api/shop'), // http://10.10.25.72:8086 /shop
	messagePrefixUrl: prepfixUrl(null, '/api/community'),
	userPrefixUrl: prepfixUrl(null, '/api/member'),
	missionPrefixUrl: prepfixUrl(null, '/api/mission'),

	get: async (url, params, config) => {
		let options = {};
		if (typeof config === 'undefined') config ={}
		options = {...options, ...config}
		if (typeof params !== 'undefined') options.data = params;
		options.method = 'GET';
		// 解决nvue不渲染问题
		return await new Promise((resolve, reject) => {
			instance(url, options).then((res) => {
				if (res && res.data && res.data.code === 200) {
					resolve(res.data);
				} else {
					reject(res && res.data);
				}
			})
		})
		// return await instance(url, options);
	},

	post: async (url, params, showErrTip = false) => {
		let options = {};
		if (typeof params !== 'undefined') options.data = params;
		options.method = 'POST';
		return await new Promise((resolve, reject) => {
			instance(url, options, showErrTip).then((res) => {
				if (res && res.data && res.data.code === 200) {
					resolve(res.data)
				} else {
					reject(res && res.data);
				}
			})
		})
		// return await instance(url, options);
	},

	put: async (url, params) => {
		let options = {};
		if (typeof params !== 'undefined') options.data = params;
		options.method = 'PUT';
		return await new Promise((resolve, reject) => {
			instance(url, options).then((res) => {
				if (res && res.data && res.data.code === 200) {
					resolve(res.data)
				} else {
					reject(res && res.data);
				}
			})
		})
		// return await instance(url, options);
	},

	delete: async (url, params) => {
		let options = {};
		if (typeof params !== 'undefined') options.data = params;
		options.method = 'DELETE';
		return await new Promise((resolve, reject) => {
			instance(url, options).then((res) => {
				if (res && res.data && res.data.code === 200) {
					resolve(res.data)
				} else {
					reject(res && res.data);
				}
			})
		})
		// return await instance(url, options);
	},

	uploadFile: async options => {
		return await new Promise((resolve, reject) => {
			instanceUploadFile(options, resolve, reject);
		})
	},
}
module.exports = http
